File Upload and Download 文件上传、下载

文件上传下载,是一般管理系统中经常会使用的操作。下面介绍下 REST 里面是如何实现的。

FileResource

我们在com.waylau.rest.resource 目录下创建 FileResource 资源类,在里面写两个路径,filepath 是文件下载路径,serverLocation 是文件上传的目录。当然 “小柳哥.txt” 这个文件是必须存在的。

  1. private static final String filepath = "D:/测试文档/小柳哥.txt";
  2. private static final String serverLocation = "D:/测试文档/";

文件下载

下载服务端

在 FileResource 资源类中添加 文件下载的代码如下:

  1. @GET
  2. @Path("download")
  3. @Consumes(MediaType.APPLICATION_JSON)
  4. @Produces(MediaType.APPLICATION_OCTET_STREAM)
  5. public Response downloadFile() {
  6. File file = new File(filepath);
  7. if (file.isFile() && file.exists()) {
  8. String mt = new MimetypesFileTypeMap().getContentType(file);
  9. String fileName = file.getName();
  10. return Response
  11. .ok(file, mt)
  12. .header("Content-disposition",
  13. "attachment;filename=" + fileName)
  14. .header("ragma", "No-cache")
  15. .header("Cache-Control", "no-cache").build();
  16. } else {
  17. return Response.status(Response.Status.NOT_FOUND)
  18. .entity("下载失败,未找到该文件").build();
  19. }
  20. }

@Produces(MediaType.APPLICATION_OCTET_STREAM) 这里就说明了,文件将会以文件流的形式返回给客户端。

下载客户端

在 index.jsp 里面添加

  1. <p><a href="webapi/files/download">Download</a>

测试

好了,代码写完,我们启动项目测试下。点击 “Download”, 此时,发现文件的名称不见了。

11. File Upload and Download 文件上传、下载 - 图1

这是因为系统解析不了编码导致的。需要将文件名称编码做下转化即可:

  1. //处理文件名称编码
  2. fileName = new String(fileName.getBytes("utf-8"),"ISO8859-1");

再次启动测试:

11. File Upload and Download 文件上传、下载 - 图2

11. File Upload and Download 文件上传、下载 - 图3

OK ,下载程序写完。

处理大数量传参下载的问题

有时难免要传递的参数较大,GET 请求难以胜任,只能用 POST 来请求下载。

下面例子就是用一个隐藏的 Form 表单来传参进行文件的下载:

  1. var exportUrl = 'rest/files/excel/easyui-datagird'
  2. var form=$("<form>");//定义一个form表单
  3. form.attr("style","display:none");
  4. form.attr("target","");
  5. form.attr("method","post");
  6. form.attr("action",exportUrl);
  7. var input1=$("<input>");
  8. input1.attr("type","hidden");
  9. input1.attr("name","fileName");
  10. input1.attr("value",fileName);
  11. var input2=$("<input>");
  12. input2.attr("type","hidden");
  13. input2.attr("name","columns");
  14. input2.attr("value",JSON.stringify(columns));
  15. var input3=$("<input>");
  16. input3.attr("type","hidden");
  17. input3.attr("name","rowsData");
  18. input3.attr("value",JSON.stringify(rows));
  19. $("body").append(form);//将表单放置在页面中
  20. form.append(input1);
  21. form.append(input2);
  22. form.append(input3);
  23. form.submit().remove();;//表单提交并

其中,input 就是用来传递参数的。input 的 name 属性是参数的名称,value 属性是参数的值。

服务端要做如下的处理:

  1. @POST
  2. @Path("excel/easyui-datagird")
  3. @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  4. @Produces(MediaType.APPLICATION_OCTET_STREAM)
  5. public Response jsonToExcle(@FormParam("fileName") String fileName,
  6. @FormParam("columns") String columns,
  7. @FormParam("rowsData") String rowsData) {
  8. //这里是处理的业务逻辑代码
  9. }

文件上传

上传文件稍微要复杂,需要 multipart/form-data 请求。

依赖

添加 jersey-media-multipart 到 pom.xml

  1. <dependency>
  2. <groupId>org.glassfish.jersey.media</groupId>
  3. <artifactId>jersey-media-multipart</artifactId>
  4. </dependency>

并在 RestApplication 里面注册 MultiPart

  1. public class RestApplication extends ResourceConfig {
  2. public RestApplication() {
  3. //资源类所在的包路径
  4. packages("com.waylau.rest.resource");
  5. //注册 MultiPart
  6. register(MultiPartFeature.class);
  7. }
  8. }

上传服务端

在 FileResource 资源类中添加 文件下载的代码如下:

  1. @POST
  2. @Path("upload")
  3. @Consumes(MediaType.MULTIPART_FORM_DATA)
  4. @Produces("application/json")
  5. public Response uploadFile(
  6. @FormDataParam("file") InputStream fileInputStream,
  7. @FormDataParam("file") FormDataContentDisposition contentDispositionHeader)
  8. throws IOException {
  9. String fileName = contentDispositionHeader.getFileName();
  10. File file = new File(serverLocation + fileName);
  11. File parent = file.getParentFile();
  12. //判断目录是否存在,不在创建
  13. if(parent!=null&&!parent.exists()){
  14. parent.mkdirs();
  15. }
  16. file.createNewFile();
  17. OutputStream outpuStream = new FileOutputStream(file);
  18. int read = 0;
  19. byte[] bytes = new byte[1024];
  20. while ((read = fileInputStream.read(bytes)) != -1) {
  21. outpuStream.write(bytes, 0, read);
  22. }
  23. outpuStream.flush();
  24. outpuStream.close();
  25. fileInputStream.close();
  26. return Response.status(Response.Status.OK)
  27. .entity("Upload Success!").build();
  28. }

上传客户端

在 index.jsp 写一个上传的 Form 表单

  1. <h3>Upload a File</h3>
  2. <form action="webapi/files/upload" method="post" enctype="multipart/form-data">
  3. <p>
  4. Select a file : <input type="file" name="file" size="50" />
  5. </p>
  6. <input type="submit" value="Upload It" />
  7. </form>

测试

选择文件,点击“Upload It”,上传成功

11. File Upload and Download 文件上传、下载 - 图4

11. File Upload and Download 文件上传、下载 - 图5

源码

file-upload-down

参考